# coding: utf-8
import os
import re

from django.core.cache import cache

from safepf.settings import SYSPATH
from apps.assetmgnt.models import Device, DevType
from apps.firewall.controler import reboot_socket
from apps.new_a4.controler import new_a4_base_requests
from apps.ids.controler import token_valid, IdsRequests
from apps.firewall3_1.controler import acquire_T3_v3_sysapi
from apps.a4api.controler import a4_api_reboot, audit_token
from apps.log_audit.controler import log_audit_base_requests
from apps.auditdb.controler import acquire_a4_info, a4_reboot
from apps.firewall.controler import send_socket, analysis_xml
from apps.firewallV2.controler import acquire_T3_v2_sysapi, firewall2_token


def reboot(ip, dtype):
    """重启设备"""
    if dtype == "T3-1.1":
        cmd = '<?xml version="1.0"?><CMD uri="set system reboot" from="admin(web@10.10.12.15)"/>'
        try:
            cont = reboot_socket(ip, cmd)
        except:
            pass
        return True
    elif dtype == "A4Api":
        tokenvl = audit_token(ip)
        flag = a4_api_reboot(ip, tokendata=tokenvl)
        if flag:
            cache.delete("%s+a4api_token" % ip, "")
    elif dtype == "A4-3.0":
        # token = cache.get("%s+new_a4_token" % ip)
        # if token:
        #     cache.delete("%s+new_a4_token" % ip)
        new_a4_base_requests(ip, addr='/api/api_v1/config/reboot/')
        cache.delete("%s+new_a4_token" % ip)
        return True
    else:
        res = a4_reboot(ip, '/system/restart/')
        return True


def shutdown(ip, dtype):
    """停止设备"""
    if dtype == "A4-3.0":
        new_a4_base_requests(ip, addr='/api/api_v1/config/shutdown/')
        cache.delete("%s+new_a4_token" % ip)
        return True


def acquire_devsoft_version(ip, dtype, model=None, _args=None):
    if dtype == "T3-1.1":
        try:
            cmd = '<?xml version="1.0"?><CMD uri="show system hosttype" from="admin(web@10.10.0.118)"></CMD>'
            res = send_socket(ip, cmd)
            tree = analysis_xml(res)
            if tree != 'ERROR' and tree != 'WRONG':
                devvision = tree.getElementsByTagName('devicetype')[0].childNodes[0].data
                sn = tree.getElementsByTagName('serialNumber')[0].childNodes[0].data
            else:
                devvision = ''
                sn = ''
        except:
            devvision, sn = '', ''

        try:
            cmd = '<?xml version="1.0"?><CMD uri="show system app_version" from="admin(web@10.10.0.118)"></CMD>'
            res = send_socket(ip, cmd)
            tree = analysis_xml(res)
            if tree != 'ERROR' and tree != 'WRONG':
                softvision = tree.getElementsByTagName('appversion')[0].childNodes[0].data
            else:
                softvision = ''
        except:
            softvision = ''
    elif dtype == "A4-3.0":
        # 新审计
        softvision = ""
        sn = ""
        devvision = ""
        res = new_a4_base_requests(ip, '/api/api_v1/config/sysinfo/')
        if res:
            softvision = res.get("soft_version", "").replace("\n", "")
            sn = res.get("sn", "")
            devvision = res.get("devtype", "")
    elif dtype[0:2] == "A4":
        res = acquire_a4_info(ip, '/system/remotesysinfo/')
        keys = list(res.keys())
        if 'devversion' in keys:
            devvision = res['devversion']
        else:
            devvision = ''
        if 'softversion' in keys:
            softvision = res['softversion']
        else:
            softvision = ''
        if 'sn' in keys:
            sn = res['sn']
        else:
            sn = ''
    elif dtype in ("T3-2.0", "T3-3.0", "T3-3.1", "T3-5.0"):
        tokendata = firewall2_token(ip, devversion=dtype)
        params = {
            "method": "exec",
            "params": [
                'decrypt_license /storage/sys_license.dat |grep -w -E "deviceVersionNick|friendlyName|deviceType|serialNumber"'
            ]
        }

        res = acquire_T3_v2_sysapi(ip=ip, params=params, tokendata=tokendata, devversion=dtype)

        if not res:
            params2 = {
                "method": "exec",
                "params": [
                    'decrypt_license /etc/sys_license.dat |grep -w -E "deviceVersionNick|friendlyName|deviceType|serialNumber"'
                ]
            }

            res = acquire_T3_v2_sysapi(ip=ip, params=params2, tokendata=tokendata, devversion=dtype)
            if not res:
                return '', '', ''

        devvision = ''
        revs = re.search('\<deviceVersionNick\>(\S+)\<\S+deviceVersionNick\>', res)
        if revs:
            devvision = revs.group(1)
        else:
            revs = re.search('\<friendlyName\>(\S+)\<\S+friendlyName\>', res)
            if revs:
                devvision = revs.group(1)
        sn = ''
        resn = re.search('\<serialNumber>(\S+)\<\SserialNumber>', res)
        if resn:
            sn = resn.group(1)

        softvision = ''
        sfparams = {
            "method": "exec",
            "params": [
                'cat /etc/openwrt_version'
            ]
        }
        try:
            sfres = acquire_T3_v2_sysapi(ip=ip, params=sfparams, tokendata=tokendata)
        except:
            sfres = acquire_T3_v3_sysapi(ip=ip, params=params, tokendata=tokendata)
        if sfres:
            softvision = "V" + sfres
    elif dtype == 'IDS':
        ids_object = IdsRequests(ip, token=_args)
        system_info = ids_object.external_call('host-info', _index=0)
        devvision = model
        softvision = system_info.get('fw_version', '')
        sn = system_info.get('serial_no', '')
    elif dtype == "LAS":
        result = log_audit_base_requests(ip, '/api/licenseInformation/sysinfo', nodata=True)
        devvision, softvision, sn = model, result.get('version_', ''), result.get('sn', '')
    else:
        devvision = ''
        softvision = ''
        sn = ''
    return devvision, softvision, sn


def change_syslog_file():
    """修改syslog配置文件、重启syslog"""
    devs = Device.objects.values_list('ip', 'dtype_id')
    if devs:
        strlist = []
        nextfw = []
        blj = []
        whitelist = []
        stand_alone_whilte = []
        als = []
        ids = []
        new_a4 = []
        for dev in devs:
            dtypename = DevType.objects.get(id=dev[1]).ename
            if dtypename == "next_filrewall":  # 下一代防火墙
                nextfw.append("$fromhost-ip=='%s'" % dev[0])
            elif "fortress_machine" in dtypename:  # 堡垒机
                blj.append("$fromhost-ip=='%s'" % dev[0])
            elif dtypename == "white-net":  # 白名单网络版
                whitelist.append("$fromhost-ip=='%s'" % dev[0])
            elif dtypename == "white-stand":  # 白名单单机版
                stand_alone_whilte.append("$fromhost-ip=='%s'" % dev[0])
            elif dtypename == "LAS":    # 日志审计
                als.append("$fromhost-ip=='%s'" % dev[0])
            elif dtypename == "IDS":    # 入侵检测
                ids.append("$fromhost-ip=='%s'" % dev[0])
            elif dtypename == 'A4-3.0':  # 新审计
                new_a4.append("$fromhost-ip=='%s'" % dev[0])
            else:
                strlist.append("$fromhost-ip=='%s'" % dev[0])
        file = open('staticmedia/storage/mysql.conf', 'r', encoding='utf-8')
        oldcnt = file.read()
        cnt = []

        if strlist:
            repstr = ' or '.join(strlist)
            cnt.append("if $msg contains 'Sub:' and (%s) then :omlibdbi:;stdSQLformatself" % repstr)
            cnt.append("if $msg contains 'sub:' and (%s) then :omlibdbi:;stdSQLformat" % repstr)
            cnt.append("if $msg contains 'host=' and (%s) then :omlibdbi:;stdSQLformatOut" % repstr)
        if nextfw:
            repstr = ' or '.join(nextfw)
            cnt.append("if $msg contains 'subtype=' and (%s)  then :omlibdbi:;stdSQLformatOutNextFirewall" % repstr)
        if blj:
            repstr = ' or '.join(blj)
            cnt.append(
                "if ($rawmsg contains '登录名' or $rawmsg contains 'Warning') and (%s)  then :omlibdbi:;stdSQLformatOutFortress" % repstr)
            cnt.append(
                "if ($msg contains 'jd_analysis' and $msg contains 'flag1' and $msg contains 'flag2') and (%s)  then :omlibdbi:;stdSQLformatOutFortressNew" % repstr)
        if whitelist:
            pass
        if stand_alone_whilte:
            repstr = ' or '.join(stand_alone_whilte)
            cnt.append("if $msg contains 'TempStr=' and (%s) then :omlibdbi:;stdSQLformatOutLuoAn" % repstr)
        if als:
            repstr = ' or '.join(als)
            cnt.append("if $msg contains '\"name\":\"ALS\"' and (%s) then :omlibdbi:;stdSQLformatInsecALS" % repstr)
        if ids:
            repstr = ' or '.join(ids)
            cnt.append("if $msg contains ' IDS 0 ' and (%s) then :omlibdbi:;stdSQLformatInsecIDS" % repstr)
            cnt.append(
                "if ($rawmsg contains 'devid=' and $rawmsg contains 'dname=') and (%s) then :omlibdbi:;stdSQLformatInsecIDSoperator" % repstr)
            cnt.append(
                "if ($rawmsg contains 'SerialNum=' and $rawmsg contains 'GenTime=')  and (%s) then :omlibdbi:;stdSQLformatInsecIDSoperatorNew" % repstr)
            cnt.append(
                "if ($msg contains ' IDS 0 ' or $msg contains ' FW 0 ' or $msg contains ' FW 1 ' or $msg contains ' FW 3 ')  and (%s) then :omlibdbi:;stdSQLformatInsecIDS" % repstr)
        if new_a4:
            repstr = ' or '.join(new_a4)
            cnt.append("if (($msg contains 'ruletp' and $msg contains 'ruleid') and not ($msg contains 'no_packet' or $msg contains 'reconnect') )  and (%s) then :omlibdbi:;stdSQLformatOutAuditNew" % repstr)
            cnt.append("if ($syslogtag contains 'snort' and ($msg contains 'Priority:' or ( $msg contains 'DDOS-' ) or ( $msg contains 'portscan' ) or ( $msg contains 'spp_frag3' )) ) and (%s) then :omlibdbi:;stdSQLformatInsecIDS" % repstr)
        file.close()

        newfile = open('staticmedia/storage/newmysql.conf', 'w+', encoding='utf-8')
        newfile.write(oldcnt)
        newcnt = '\n'.join(cnt)
        newfile.write(newcnt)
        newfile.close()
        os.system('mv %sstaticmedia/storage/newmysql.conf /etc/rsyslog.d/mysql.conf' % SYSPATH)
    else:
        os.system('cp %sstaticmedia/storage/mysql.conf /etc/rsyslog.d/mysql.conf' % SYSPATH)
    os.system('killall -9 rsyslogd')
    os.system('/etc/init.d/rsyslog start')
    os.system('/etc/init.d/inssecevent restart')
    return
